/*
 * Copyright 2011 myTDev.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.mytdev.commons.util;

import com.mytdev.commons.text.EnumParserFactory;
import com.mytdev.commons.text.Parser;
import com.mytdev.commons.text.ServiceParserFactory;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.io.File;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.URL;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Locale;
import java.util.regex.Pattern;

/**
 *
 * @author Yann D'Isanto
 */
public abstract class AbstractPropertiesAccessor implements PropertiesAccessor {
    
    private <T> Parser<? extends T> getParser(Class<T> type) {
        Parser<? extends T> parser = null;
        if(Enum.class.isAssignableFrom(type)) {
            parser = EnumParserFactory.getInstance().getParser(type);
        } else {
            parser = ServiceParserFactory.getInstance().getParser(type);
        }
        return parser;
    }
    
    @Override
    public String get(Enum<?> key) {
        return get(key.toString());
    }

    @Override
    public <T> T get(String key, Class<T> type) {
        Parser<? extends T> parser = getParser(type);
        if(parser == null) {
            throw new IllegalArgumentException("unsupported type: " + type.getName());
        }
        String value = get(key);
        if(value == null) {
            return null;
        }
        try {
            return parser.parse(value);
        } catch (ParseException ex) {
            throw new IllegalArgumentException(ex.getLocalizedMessage(), ex);
        }
    }
    
    @Override
    public <T> T get(Enum<?> key, Class<T> type) {
        return get(key.toString(), type);
    }

    @Override
    public BigDecimal getBigDecimal(Enum<?> key) {
        return getBigDecimal(key.toString());
    }

    @Override
    public BigDecimal getBigDecimal(String key) {
        return get(key, BigDecimal.class);
    }

    @Override
    public BigInteger getBigInteger(Enum<?> key) {
        return getBigInteger(key.toString());
    }

    @Override
    public BigInteger getBigInteger(String key) {
        return get(key, BigInteger.class);
    }

    @Override
    public boolean getBoolean(Enum<?> key) {
        return getBoolean(key.toString());
    }

    @Override
    public boolean getBoolean(String key) {
        return get(key, Boolean.TYPE);
    }

    @Override
    public byte getByte(Enum<?> key) {
        return getByte(key.toString());
    }

    @Override
    public byte getByte(String key) {
        return get(key, Byte.TYPE);
    }

    @Override
    public char getChar(Enum<?> key) {
        return getChar(key.toString());
    }

    @Override
    public char getChar(String key) {
        return get(key).charAt(0);
    }

    @Override
    public Color getColor(Enum<?> key) {
        return getColor(key.toString());
    }

    @Override
    public Color getColor(String key) {
        return get(key, Color.class);
    }

    @Override
    public DateFormat getDateFormat(Enum<?> key) {
        return getDateFormat(key.toString());
    }

    @Override
    public DateFormat getDateFormat(String key) {
        return get(key, DateFormat.class);
    }

    @Override
    public Dimension getDimension(Enum<?> key) {
        return getDimension(key.toString());
    }

    @Override
    public Dimension getDimension(String key) {
        return get(key, Dimension.class);
    }

    @Override
    public double getDouble(Enum<?> key) {
        return getDouble(key.toString());
    }

    @Override
    public double getDouble(String key) {
        return get(key, Double.TYPE);
    }

    @Override
    public File getFile(Enum<?> key) {
        return getFile(key.toString());
    }

    @Override
    public File getFile(String key) {
        return get(key, File.class);
    }

    @Override
    public float getFloat(Enum<?> key) {
        return getFloat(key.toString());
    }

    @Override
    public float getFloat(String key) {
        return get(key, Float.TYPE);
    }

    @Override
    public Font getFont(Enum<?> key) {
        return getFont(key.toString());
    }

    @Override
    public Font getFont(String key) {
        return get(key, Font.class);
    }

    @Override
    public InetAddress getInetAddress(Enum<?> key) {
        return getInetAddress(key.toString());
    }

    @Override
    public InetAddress getInetAddress(String key) {
        return get(key, InetAddress.class);
    }

    @Override
    public int getInt(Enum<?> key) {
        return getInt(key.toString());
    }

    @Override
    public int getInt(String key) {
        return get(key, Integer.TYPE);
    }

    @Override
    public Locale getLocale(Enum<?> key) {
        return getLocale(key.toString());
    }

    @Override
    public Locale getLocale(String key) {
        return get(key, Locale.class);
    }

    @Override
    public long getLong(Enum<?> key) {
        return getLong(key.toString());
    }

    @Override
    public long getLong(String key) {
        return get(key, Long.TYPE);
    }

    @Override
    public Pattern getPattern(Enum<?> key) {
        return getPattern(key.toString());
    }

    @Override
    public Pattern getPattern(String key) {
        return get(key, Pattern.class);
    }

    @Override
    public short getShort(Enum<?> key) {
        return getShort(key.toString());
    }

    @Override
    public short getShort(String key) {
        return get(key, Short.TYPE);
    }

    @Override
    public URL getURL(Enum<?> key) {
        return getURL(key.toString());
    }

    @Override
    public URL getURL(String key) {
        return get(key, URL.class);
    }
}
